import { Request, Response } from 'express';
import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';

@Catch()
export class AppFilter implements ExceptionFilter {
  // 全局的异常捕获
  private readonly logger = new Logger(AppFilter.name);
  private readonly intenalError = 'Internet Server Error';

  private getStatusCode(exception: any) {
    let statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
    if (exception instanceof HttpException) {
      statusCode = exception.getStatus();
    }
    return statusCode;
  }

  private getErrorMessage(exception: any) {
    if (exception instanceof HttpException) {
      return exception?.message;
    }
    return this.intenalError;
  }

  catch(exception: any, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const request = ctx.getRequest<Request>();
    const response = ctx.getResponse<Response>();
    const statusCode = this.getStatusCode(exception);

    try {
      let baseResponse = {
        url: request?.url,
        requestId: request.get('requestId'),
      };

      const errorMessage = this.getErrorMessage(exception);
      const errorResponse = exception?.getResponse();
      if (typeof errorResponse === 'string') {
        baseResponse['message'] = errorResponse;
      } else {
        Object.assign(baseResponse, errorResponse);
      }

      if (statusCode === HttpStatus.INTERNAL_SERVER_ERROR) {
        Object.assign(baseResponse, {
          stack: exception?.stack,
        });
      }
      this.logger.error(exception?.message, [AppFilter.name, baseResponse]);
      response.status(statusCode).json({
        code: -1,
        message: errorMessage,
        data: baseResponse,
      });
    } catch (error) {
      this.logger.error(error?.stack, [AppFilter.name, {}]);
      response.status(statusCode).json({
        code: -1,
        message: this.intenalError,
        data: null,
      });
    }
  }
}
